<script setup>
import { nextTick, ref } from "vue";
import { onLoad, onReachBottom, onShow } from "@dcloudio/uni-app";
import { get } from "@/request/request";
import { config } from "@/config";
import TnNavbar from '@tuniao/tnui-vue3-uniapp/components/navbar/src/navbar.vue'
import TnIcon from '@tuniao/tnui-vue3-uniapp/components/icon/src/icon.vue'
import TnTabs from '@tuniao/tnui-vue3-uniapp/components/tabs/src/tabs.vue'
import TnTabsItem from '@tuniao/tnui-vue3-uniapp/components/tabs/src/tabs-item.vue'
import TnSwiper from '@tuniao/tnui-vue3-uniapp/components/swiper/src/swiper.vue'
import TnTitle from '@tuniao/tnui-vue3-uniapp/components/title/src/title.vue'
import TnPopup from '@tuniao/tnui-vue3-uniapp/components/popup/src/popup.vue'
import TnSearchBox from '@tuniao/tnui-vue3-uniapp/components/search-box/src/search-box.vue'
import loginModale from '@/pages/components/login.vue';

const currentTabIndex = ref(0);
const currentSwiperIndex = ref(0);
const showPopup = ref(false);
const topValue = ref('选择班级');
const courseList = ref([]);
const position = ref("3");
const isVip = ref(false);

const gradeOptions = ref([]);//年级数据
const catOptions = ref([]);//分类数据

const isEmpty = ref(false);
const searchForm = ref({
  page: 1,
  pageSize: 5,
  key: '',
  grade: 0,
  cat: -1
})

const downloadProgress = ref(0);
const showProgress = ref(false);

onLoad(() => {
  getGrade();
  getCat();
  getList();
  swiperDataData();
})
onShow(() => {
  get_vip()
})
//搜索
const searchClick = () => {
  uni.navigateTo({
    url: '/pages/search/search'
  })
}

//tabs
const getCat = () => {
  get('/public_api/get_cat').then(res => {
    const { data } = res;
    data.unshift({ id: -1, name: '精选' })
    catOptions.value = data

  })
}

// 轮播图数据
const swiperData = ref([]);
const swiperDataData = () => {
  get('/public_api/get_advert', { position: position.value }).then(res => {
    swiperData.value = res.data;
  })
}

//年级
const getGrade = () => {
  get('/public_api/get_grade').then(res => {
    const { data } = res;
    gradeOptions.value = data
  })
}


const topPopup = () => {
  showPopup.value = true;
}


//选择年级
const eleClick = (item) => {

  if (searchForm.value.grade !== 0 && item.id === searchForm.value.grade) {
    searchForm.value.grade = 0;
    topValue.value = '请选年级'
  } else {
    searchForm.value.grade = item.id;
    topValue.value = item.name;
  }
  courseList.value = [];
  showPopup.value = false;
  getList();
};


//选择分类
const tabsClick = (item) => {
  searchForm.value.cat = item.id;
  searchForm.value.page = 1;
  courseList.value = [];
  isEmpty.value = false;
  getList();
}


//资料预览
const loginAuth = ref(false);

const experience = (item) => {
  if (uni.getStorageSync("sessionKey") && uni.getStorageSync('auth')) {
    const fileType = item.extend.toLowerCase();
    if (fileType === 'pdf') {
      handlePdfDownload(item);
    } else {
      uni.navigateTo({
        url: '/pages/material/components/file-preview?id=' + item.id
      })
    }
  } else {
    nextTick(() => {
      uni.showModal({
        title: '提示',
        content: '您还没登录，请先登录',
        confirmColor: '#0045cf',
        success: function (res) {
          if (res.confirm) {
            loginAuth.value = true;
          } else if (res.cancel) {
            uni.switchTab({
              url: '/pages/index/index'
            });
          }
        }
      });
    })
  }
}

const handlePdfDownload = async (item) => {
  showProgress.value = true;
  try {
    // 先获取文件信息
    const fileInfo = await get('/get_material', { id: item.id }, { "sessionKey": uni.getStorageSync("sessionKey") });
    if (!fileInfo.data || !fileInfo.data.src) {
      throw new Error('获取文件信息失败');
    }

    const downloadUrl = config.baseUrl + '/file/' + fileInfo.data.src;
    console.log('开始下载PDF, URL:', downloadUrl);

    const completeBuffer = await fetchCompletePDF(downloadUrl);
    console.log('PDF下载完成, 大小:', completeBuffer.byteLength);

    const fileName = `temp_${Date.now()}.pdf`;
    const filePath = `${uni.env.USER_DATA_PATH}/${fileName}`;
    console.log('临时文件路径:', filePath);

    const fs = uni.getFileSystemManager();

    console.log('开始写入文件...');
    await new Promise((resolve, reject) => {
      fs.writeFile({
        filePath,
        data: completeBuffer,
        encoding: 'binary',
        success: (res) => {
          console.log('文件写入成功');
          resolve(res);
        },
        fail: (err) => {
          console.error('文件写入失败:', err);
          reject(err);
        }
      });
    });

    const stat = fs.statSync(filePath);
    console.log('写入文件大小:', stat.size);
    if (stat.size === 0) {
      throw new Error('文件写入失败，文件大小为0');
    }

    console.log('开始打开文件...');
    await new Promise((resolve, reject) => {
      uni.openDocument({
        filePath,
        fileType: 'pdf',
        showMenu: true,
        success: (res) => {
          console.log('文件打开成功:', res);
          resolve(res);
        },
        fail: (err) => {
          console.error('文件打开失败:', err);
          reject(err);
        }
      });
    });

    showProgress.value = false;

    setTimeout(() => {
      try {
        fs.unlinkSync(filePath);
        console.log('临时文件删除成功');
      } catch (e) {
        console.error('清理临时文件失败:', e);
      }
    }, 5000);

  } catch (err) {
    console.error('PDF处理失败:', err);
    uni.showToast({
      title: '文件打开失败，请重试',
      icon: 'none'
    });
    showProgress.value = false;
  }
};

const fetchCompletePDF = async (url) => {
  try {
    console.log('开始检查服务器是否支持断点续传, url:', url);

    const headRes = await uni.request({
      url: url,
      method: 'HEAD'
    });

    console.log('HEAD请求响应头(JSON):', JSON.stringify(headRes.header, null, 2));

    let totalSize = 0;
    if (headRes.header['Content-Range']) {
      const match = headRes.header['Content-Range'].match(/bytes \d+-\d+\/(\d+)/);
      if (match) {
        totalSize = parseInt(match[1]);
      }
    } else if (headRes.header['Content-Length']) {
      totalSize = parseInt(headRes.header['Content-Length']);
    }

    if (totalSize === 0) {
      return await downloadComplete(url);
    }

    let fileData = [];
    const chunkSize = 1024 * 1024; // 1MB chunks
    let start = 0;

    while (start < totalSize) {
      const end = Math.min(start + chunkSize - 1, totalSize - 1);
      console.log(`下载分片: ${start}-${end}, 大小: ${end - start + 1} bytes`);

      const res = await uni.request({
        url: url,
        method: 'GET',
        header: {
          'Range': `bytes=${start}-${end}`
        },
        responseType: 'arraybuffer'
      });

      if (res.statusCode !== 206) {
        return await downloadComplete(url);
      }

      if (!res.data || res.data.byteLength === 0) {
        return await downloadComplete(url);
      }

      fileData.push(res.data);
      start = end + 1;
      downloadProgress.value = Math.min((start / totalSize) * 100, 100);
    }

    const totalLength = fileData.reduce((acc, buffer) => acc + buffer.byteLength, 0);
    if (totalLength !== totalSize) {
      return await downloadComplete(url);
    }

    const mergedArrayBuffer = new Uint8Array(totalLength);
    let offset = 0;

    fileData.forEach((buffer) => {
      mergedArrayBuffer.set(new Uint8Array(buffer), offset);
      offset += buffer.byteLength;
    });

    return mergedArrayBuffer.buffer;
  } catch (error) {
    console.error('下载PDF文件失败:', error);
    return await downloadComplete(url);
  }
};

const downloadComplete = async (url) => {
  const res = await uni.request({
    url: url,
    method: 'GET',
    responseType: 'arraybuffer'
  });

  if (res.statusCode !== 200 && res.statusCode !== 206) {
    throw new Error(`请求失败，状态码：${res.statusCode}`);
  }

  downloadProgress.value = 100;
  return res.data;
};

const get_vip = () => {
  get('/get_vip_data', null, { "sessionKey": uni.getStorageSync("sessionKey") }).then(res => {
    console.log('会员', res)
    const { data } = res;
    isVip.value = data
  })
}
//资料

onReachBottom(() => {
  if (!isEmpty.value) {
    searchForm.value.page += 1;
  }
  getList();
})

const getList = () => {
  get('/public_api/material_list', searchForm.value).then(res => {
    if (res.data.list.length === 0) {
      isEmpty.value = true;
      searchForm.value.page = searchForm.value.page;
    } else {
      isEmpty.value = false;
    }
    courseList.value = [...courseList.value, ...res.data.list]
  })
}
//分享
const onShareAppMessage = (res) => {
  if (res.from === 'button') {
  }
  return {
    title: '请家教，来找我',
    path: '/pages/index/index'
  }
}
</script>


<template>
  <TnNavbar fixed>
    <template #back>
      <view class="back" @click="topPopup">
        <view>{{ topValue }}</view>
        <TnIcon name="down-triangle" color="#0d57d6" />
      </view>
    </template>
  </TnNavbar>
  <view class="app">
    <view class="sreach_box">
      <view style="padding: 10rpx;">
        <TnSearchBox size="sm" :clearable="false" :search-button="false" shape="round" :disabled="true"
          @click="searchClick" />
      </view>
    </view>
    <TnTabs v-model="currentTabIndex" active-color="tn-blue-dark" bar-color="#0052D9">
      <TnTabsItem v-for="(item, index) in catOptions" :key="index" :title="item.name" :bottom-shadow="false"
        @click="tabsClick(item)" />
    </TnTabs>
    <view class="SwiperBox">
      <TnSwiper v-model="currentSwiperIndex" :data="swiperData" height="228" width="694" indicator :loop="true"
        :autoplay="true">

        <template #default="{ data }">
          <view class="swiper-data">
            <image :src="config.baseUrl + '/file/' + data.src" class="image" />
          </view>
        </template>
      </TnSwiper>
    </view>
    <view class="tn_title">
      <TnTitle size="xl" title="资料" />
    </view>
    <view v-for="(item, index) in courseList" :key="index" class="information">
      <image :src="config.baseUrl + '/file/' + item.img" />
      <view class="introduce">
        <text style="font-size: 32rpx">{{ item.title }}</text>
        <view style="font-size: 24rpx">格式：{{ item.extend }}</view>
        <view class="experience">
          <view class="nce">
            <image src="/static/material/eye.svg" />
            <text>{{ item.preview }}次浏览</text>
          </view>
          <view class="nce">
            <image src="/static/material/support.svg" />
            <text>{{ item.likes }}</text>
          </view>
          <view class="btn" @click="experience(item)">立即体验</view>
        </view>
      </view>
    </view>
  </view>

  <TnPopup v-model="showPopup" open-direction="bottom" :close-btn="true">
    <view class="popup_Title">请选择班级</view>
    <view class="popup">
      <template v-for="item in gradeOptions">
        <TnTitle size="lg" :title="item.name" />
        <view class="ele_box">
          <view v-for="item1 in item.children" class="elementary"
            :class="searchForm.grade == item1.id ? 'selected' : ''" @click="eleClick(item1)">
            {{ item1.name }}
          </view>
        </view>
      </template>
    </view>
  </TnPopup>
  <!-- 登录组件 -->
  <loginModale v-model:show="loginAuth" />

  <view class="mask" v-if="showProgress">
    <view class="progress-popup">
      <view class="progress-title">文件下载中</view>
      <view class="progress-container">
        <view class="progress-bar" :style="{ width: `${downloadProgress}%` }"></view>
      </view>
      <view class="progress-text">{{ parseInt(downloadProgress) }}%</view>
    </view>
  </view>
</template>

<style scoped lang="scss">
.back {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: space-around;
  color: #0d57d6;

  image {
    height: 40rpx;
    width: 40rpx;
  }
}

.app {
  .sreach_box {
    width: 100%;
    height: 80rpx;
    background: #FFFFFF;
    text-align: center;
  }

  .SwiperBox {
    padding: 10rpx;
    margin: 10rpx;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;

    .swiper-data {
      width: 100%;
      height: 100%;
      border-radius: 20rpx;

      .image {
        width: 100%;
        height: 100%;
        border-radius: inherit;
      }
    }
  }

  .tn_title {
    padding: 15rpx;
    margin: 15rpx;
  }

  .information {
    padding: 10rpx;
    margin: 16rpx;
    height: 200rpx;
    width: 694rpx;
    background: #FFFFFF;
    border-radius: 12rpx;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: left;

    image {
      width: 152rpx;
      height: 200rpx;
      margin: -9rpx;
    }

    .introduce {
      margin: 30rpx;
      height: 200rpx;
      display: flex;
      justify-content: space-evenly;
      flex-direction: column;

      .experience {
        height: 56rpx;
        width: 480rpx;
        display: flex;
        align-items: center;
        justify-content: space-between;

        .nce {
          display: flex;
          align-items: center;
          justify-content: center;

          image {
            margin: 10rpx;
            height: 24rpx;
            width: 24rpx;
          }

          text {
            font-size: 24rpx;
          }
        }

        .btn {
          display: flex;
          align-items: center;
          justify-content: center;
          height: 56rpx;
          width: 152rpx;
          border-radius: 9999rpx;
          border: 2rpx solid #0052D9;
          color: #0052D9;
          font-size: 28rpx;
          font-weight: 800;
        }
      }
    }
  }
}

.popup_Title {
  padding: 20rpx;
  width: 100%;
  text-align: center;
  font-size: 40rpx;
  margin-top: 5rpx;
}

.popup {
  padding: 20rpx;

  .kindergarten {
    margin: 10rpx;
    width: 212rpx;
    height: 80rpx;
    background: #f3f3f3;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 999rpx;
  }

  .ele_box {
    display: flex;
    flex-wrap: wrap;
  }

  .elementary {
    margin: 10rpx;
    width: 212rpx;
    height: 80rpx;
    background: #f3f3f3;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 999rpx;
  }

  .selected {
    background: #0d57d6;
    color: #ffffff;
  }
}

.mask {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 999;
}

.progress-popup {
  background-color: #fff;
  border-radius: 24rpx;
  padding: 40rpx;
  width: 600rpx;

  .progress-title {
    font-size: 32rpx;
    color: #333;
    margin-bottom: 30rpx;
    text-align: center;
  }

  .progress-container {
    height: 40rpx;
    background-color: #f5f5f5;
    border-radius: 20rpx;
    overflow: hidden;
    margin-bottom: 20rpx;
  }

  .progress-bar {
    height: 100%;
    background-color: #0052D9;
    transition: width 0.3s ease;
  }

  .progress-text {
    text-align: center;
    font-size: 28rpx;
    color: #666;
  }
}
</style>
